Skip to content

Round 44 batch 5 of 6: BACKLOG-per-row-file restructure ADR (draft)#85

Closed
AceHack wants to merge 4 commits intoLucent-Financial-Group:mainfrom
AceHack:land-backlog-per-row-file-batch5
Closed

Round 44 batch 5 of 6: BACKLOG-per-row-file restructure ADR (draft)#85
AceHack wants to merge 4 commits intoLucent-Financial-Group:mainfrom
AceHack:land-backlog-per-row-file-batch5

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 22, 2026

Summary

Batch 5 of the 6-batch speculative-branch drain plan
(docs/research/speculative-branch-landing-plan-2026-04-22.md).
Solo landing of a single ADR draft — smallest batch in
the plan, zero CI risk beyond markdownlint.

What this lands

  • docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
    — 288-line ADR proposing a per-row-file restructure of
    docs/BACKLOG.md (splitting the monolithic file into
    one file per row under docs/backlog-rows/). Status:
    Proposed, not Accepted. Aaron decides the four open
    questions out-of-band via HB-002.

Why ship as Proposed

Landing a Proposed ADR captures the shape of the
proposal and its four open questions on main so:

  • The reasoning is preserved in git (soul-file
    reproducibility per memory/user_git_repo_is_factory_soul_file_...)
  • Future rounds can cite the ADR by filename even before
    it's Accepted
  • HB-002 (Aaron's decision on four questions) has a
    stable doc to reference

The four open questions parked for Aaron:

  1. ID scheme (sequential, date-based, or UUID?)
  2. Script home (where does the migration script live?)
  3. Sort order on generated BACKLOG.md index
  4. Concurrent-migration trade (big-bang vs incremental?)

Drain-PR pre-check

Ran the memory/(user|feedback|project|reference)_|\baaron\b
grep on commit 89876b7 (cherry-pick of 9f31cb6) — 0 hits.
Clean batch.

Not in this PR

  • Does not migrate any BACKLOG row. Proposed-only.
  • Does not add the migration script. Post-HB-002.
  • Does not file HB-002 in this PR (HB-002 is a
    human-backlog row that Aaron files or the next BACKLOG
    update proposes).

Test plan

  • Cherry-pick of 9f31cb6 is clean
  • Pre-check grep on commit 89876b7 — 0 hits
  • markdownlint passes on the new ADR
  • CI green
  • Auto-merge resolves when CI clears

…ive for R45)

Drafted on round-44-speculative (no CI trigger) while PR #36 §9
incident-log CI runs, per wait-on-build + never-idle factory memories.

Status: Proposed. Triggered by PR #31 merge-tangle 5-file conflict
fingerprint captured in docs/research/parallel-worktree-safety-
2026-04-22.md §9. ADR proposes splitting the 5,957-line monolithic
BACKLOG.md into index + per-row files under docs/backlog/<tier>/.

Key content:
- Per-row-file directory shape with frontmatter schema
  (id/tier/created/updated/owner/effort/scope).
- Index-file shape (short, one line per row, ~500 lines max even
  at scale).
- Migration plan (single mechanical transform PR, zero semantic
  edits, ships in one round).
- Authoring rules post-migration (add / edit / ship / tier-change).
- Alternatives: append-only-section, per-tier split, editor lock,
  automated resolver — all rejected with reasons.
- Consequences tallied positive/negative/neutral.
- Revised R45-R49 staging: delay R45 EnterWorktree flip by one
  round; land restructure first. Justification: preventive+
  compensating discipline fails without it.
- Open questions (ID scheme / script home / sort order /
  concurrent-migration trade) flagged for Aaron's decision on
  wake.

Promotion path: review + land on a separate PR after PR #36
merges. This commit is the draft; no BACKLOG.md touched yet.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 22, 2026 03:51
@AceHack AceHack enabled auto-merge (squash) April 22, 2026 03:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a draft ADR documenting a proposed restructure of docs/BACKLOG.md into per-row files to reduce merge conflicts and shared-write churn in the factory docs workflow.

Changes:

  • Introduces a new ADR (Status: Proposed) describing a per-row-file backlog layout, migration approach, and staging plan.
  • Defines suggested directory/file shapes and authoring rules for the post-migration workflow.

Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Copilot AI review requested due to automatic review settings April 22, 2026 04:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.

Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
Comment thread docs/DECISIONS/2026-04-22-backlog-per-row-file-restructure.md
AceHack added a commit that referenced this pull request Apr 22, 2026
* Round 44 tick-history: auto-loop-2 PR refresh row

Second post-compaction tick. PR #91 refresh after PR #90 merged
4ac3ec3 on main mid-tick; PR #46 refresh after stale-local
reset (bc93188..63720e5). Fork PRs #88/#85/#52/#54 noted as
un-refreshable from current agent harness.

Tick-commits-on-PR-branch = live-loop class (row 112) preserved
via separate branch land-tick-history-autoloop-2-append off
origin/main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* tick-history row fixes — Copilot findings on PR #92

Three fixes to the auto-loop-2 row:
1. Drop "AceHack" handle → "fork ownership outside the canonical
   repo" (BP-L284-L290 compliance)
2. Full ISO8601 timestamp (2026-04-22T04:20:00Z) per file schema
3. Drop self-referential "(row 112 of this file)"

Pre-check grep expanded to include "acehack" handle — prior
grep only caught "aaron" + memory/* refs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 22, 2026
… merged; pure-refresh tick (#100)

* Round 42 (auto-loop-7): tick-history row — bootstrap-precursor drift-taxonomy absorb

Appends row narrating the auto-loop-7 tick that landed PR #96
(docs/research/drift-taxonomy-bootstrap-precursor-2026-04-22.md).

Tick substance:

- Playwright MCP round-trip fetching a pre-repo artifact (share-URL
  passed Cloudflare challenge that blocked WebFetch the prior tick);
  second attempt on private-account URL correctly denied by permission
  guard under broad authorization, then proceeded under narrow-scope
  ("log for research") consent after a clean consent-shape round-trip.
- Research-grade absorb landed with four hallucinations flagged by the
  same taxonomy the artifact introduces (self-reflexive application).
- Scope discipline held: IDEAS absorbed, entity-as-entity stays in its
  substrate per register-boundary.
- Key recalibration: auto-loop-6's cross-substrate-report-accuracy-rate
  measurable reads weaker with new provenance info — the convergence
  was maintainer-transported vocabulary, not independent arrival. Spec
  update: accuracy scored against *factory positions at the time of
  the report*, not *positions the report can plausibly have inherited
  via carrier-channel*.

Row lands on a separate branch off origin/main per
tick-commits-on-PR-branch = live-loop class discipline (row 112). Pre-
check grep discipline applied on added row content (EXIT=1 on the added
row only; file as a whole contains prior rows with Zeta org-name in
PR URL fragments — factual historical record, not prose attribution).

* Round 44 tick-history: auto-loop-8 append row (PR refreshes + BACKLOG carrier-channel row + maintainer read-sync)

Append one tick-history row narrating the auto-loop-8 fire:
(a) PR #97 refresh against advancing main (6bbf302..eee554a);
(b) PR #93 refresh against advancing main (c1a4863..7fe4feb);
(c) P2 BACKLOG carrier-channel measurable-refinement row landed
    as PR #98 with measurable-split + provenance-check + anti-
    pattern doc + effort-S back-scoring plan;
(d) maintainer mid-tick read-sync on PR #96 answered inline
    with SHA + timestamp + path + line-count + reading-order
    guidance.

Row sits after auto-loop-7 at line 118. Separate branch off
origin/main-post-#97 per live-loop-class tick-history
discipline (row 112). Pre-check grep clean (0 contributor-name
hits, 0 cross-tree auto-memory path hits).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Round 44 tick-history: auto-loop-9 append row (three non-fork PR refreshes after PR #98 merged; pure-refresh tick)

Append one tick-history row narrating the auto-loop-9 fire:
(a) PR #99 refresh against advancing main — 4cf9c1b..d851940;
(b) PR #97 refresh against advancing main — eee554a..f7fc960;
(c) PR #93 refresh against advancing main — 7fe4feb..b698d1c;
(d) PR #85 noted fork-unrefreshable — queued BACKLOG gap.

No content work this tick — pure operational-maintenance.
Tmp-worktree-clone pattern used for refreshes to avoid stale-
local branch-switch churn.

Reflection field introduces candidate instrumentation
`open-pr-refresh-debt` as a meta-measurable for merge-tangle
risk under advancing-main pressure.

Separate branch off origin/main with auto-loop-8 branch merged
in per live-loop-class discipline + stacked-dependency pattern.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 25, 2026
…dex)

Otto-268 follow-on: drain-log for the 4-finding cascade PR #430
(post-merge follow-up to #221 Amara 4th courier ferry absorb).
Captures four substantive Codex post-merge corrections.

Per Otto-250 training-signal discipline. Pattern observations:

1. Verbatim-claim accuracy under absorbing-side annotation —
   "preserved verbatim" claims must reflect any absorbing-side
   annotations (proposal-flag markers, footnotes, inline bracketing).
   Same shape as #235's "byte-for-byte ... excluding whitespace"
   contradiction fix.
2. Count-vs-list cardinality is now a 4th-observation pattern
   (#191 / #219 / #430 / #85). At this density, pre-commit-lint
   candidate: regex on "N drift classes / phases / audits / items"
   patterns + count the surrounding list to verify.
3. Terminology drift between parent absorb + canonical vocabulary
   ("decision-proxy-consult" vs canonical "decision-proxy-evidence")
   is recurring. Fix template: align absorption-notes text to
   canonical; preserve verbatim ferry content per Otto-227.
4. Stabilize effort-summary correction is a concrete instance of
   "claim summary doesn't match per-item tally" — future doc-lint
   candidate (sum-vs-tally check).
AceHack added a commit that referenced this pull request Apr 25, 2026
…dex) (#461)

* hygiene(#268+): pr-preservation drain-log for #430 (#221 follow-up Codex)

Otto-268 follow-on: drain-log for the 4-finding cascade PR #430
(post-merge follow-up to #221 Amara 4th courier ferry absorb).
Captures four substantive Codex post-merge corrections.

Per Otto-250 training-signal discipline. Pattern observations:

1. Verbatim-claim accuracy under absorbing-side annotation —
   "preserved verbatim" claims must reflect any absorbing-side
   annotations (proposal-flag markers, footnotes, inline bracketing).
   Same shape as #235's "byte-for-byte ... excluding whitespace"
   contradiction fix.
2. Count-vs-list cardinality is now a 4th-observation pattern
   (#191 / #219 / #430 / #85). At this density, pre-commit-lint
   candidate: regex on "N drift classes / phases / audits / items"
   patterns + count the surrounding list to verify.
3. Terminology drift between parent absorb + canonical vocabulary
   ("decision-proxy-consult" vs canonical "decision-proxy-evidence")
   is recurring. Fix template: align absorption-notes text to
   canonical; preserve verbatim ferry content per Otto-227.
4. Stabilize effort-summary correction is a concrete instance of
   "claim summary doesn't match per-item tally" — future doc-lint
   candidate (sum-vs-tally check).

* drain(#461 follow-up): fix count mismatches + add merge SHA in #430 drain-log

Multiple Codex/Copilot threads on #461 caught:

- L7 'Thread count at drain: 3' → '4' (body has Threads 1-4).
- L17 'Codex caught three findings' → 'four' matching body.
- L122 'merged to main' → 'merged to main as `5698f9d`' for
  consistency with other drain-logs that include the merge SHA
  for auditability.

Same count-vs-list cardinality pattern (Class B in PR #465 doc-lint
suite BACKLOG row) — 5th instance in my own drain-logs (#195 / #231
/ #377 / #135 / #430). The pattern is genuinely universal author-
side; even when explicitly aware of it, instances slip through.
AceHack added a commit that referenced this pull request Apr 25, 2026
…reword)

Otto-268 backfill: drain-log for PR #435 (drain follow-up to #148:
why-the-factory-is-different live-lock cadence claim + grammar),
covering 3 threads across 2 waves with a clean self-induced-cascade
pattern.

Per Otto-250 training-signal discipline. Pattern observations capture
four load-bearing patterns:
1. Cross-reviewer convergence on Wave 1 (Codex P2 + Copilot P1
   flagging the same missing-FACTORY-HYGIENE-row) raised quality
   signal — same shape as #432's `warn` unbound finding.
2. Self-induced cascade: my Wave-1 fix introduced the Wave-2
   finding (claim "separate BACKLOG items" implied plural; actual
   BACKLOG state is one row with multiple sub-items). Pattern: when
   fixing a claim, verify the new claim is also accurate against
   current-state.
3. Reword-option-(a)-vs-(b) decision template generalizes: when
   doc asserts X but X doesn't exist, prefer reword-to-current-truth
   over add-the-thing-asserted (unless thing is small + isolated).
4. PR-mechanics: 4 of 7 cascade-PRs in this session (#135, #231,
   #432, #435) went through wave-1 + wave-2 cascade pattern; the
   reviewer-cascade is a consistent property of the merge-trigger
   surface, not a per-PR oddity.

Closes the session-drain-log backfill (Otto-268) for the major PRs
drained in this session: #135 / #235 / #432 / #434 / #195 / #219 /
#206 / #377 / #231 / #85 / #435 (11 PRs total covered across drain
logs #437-#447).
AceHack added a commit that referenced this pull request Apr 25, 2026
#464)

* hygiene(#268+): pr-preservation drain-log for #426 (tick-history meta-record)

Otto-268 follow-on: drain-log for the **meta-record** PR #426
(tick-history append summarizing the 28-thread sustained-drain-wave
on 2026-04-25T04:15:00Z). The wave-summary itself attracted 3
post-merge findings on text accuracy.

Per Otto-250 training-signal discipline. Pattern observations:

1. Tick-history meta-records get drained too — drain corpus is
   recursive. Every PR that lands gets reviewer-cascade attention
   regardless of substantive vs meta content.
2. Otto-229 append-only correction-row pattern applied uniformly:
   original row stays untouched; correction rows point back at the
   original timestamp.
3. Pipe-in-Markdown-table-row is a recurring formatting class —
   inline code spans containing `|` get parsed as column
   separators. Earlier `||` issues + MD056 hits; #426 has it with
   `|` in a `read -rs | printf` command. Pre-commit-lint candidate.
4. Count-vs-list cardinality observed at 5 PRs now (#191, #219,
   #430, #85, #426). Pattern is mature enough that automation
   would pay back across the entire drain corpus.

* hygiene(#464): align intro PR-list with canonical (a)-(h) enumeration

Codex P2: intro listed 6 PRs as the wave scope but the canonical
(a)-(h) enumeration in Thread 1 covers 8 PRs (#414, #422, #423,
#425, #268, #270, #126, #133). Same count-vs-list cardinality
pattern documented in _patterns.md Class B (Otto-268). Reword
intro to match the authoritative 8-PR list.
AceHack added a commit that referenced this pull request Apr 25, 2026
* backlog: P2 doc-lint suite — recurring drain-finding classes promoted

Compounding-substrate work on Otto-268+ drain-log corpus: three
findings classes from `docs/pr-preservation/_patterns.md` have
reached observation density warranting pre-commit-lint automation.

Classes promoted to BACKLOG:

A. Inline-code-span line-wrap (4 PRs: #191, #195, #219, #423).
   Regex check for backtick spans crossing newlines.
B. Count-vs-list cardinality (5 PRs: #191, #219, #430, #85, #426).
   Regex on "N items / phases / audits / drift classes / PRs"
   patterns + count surrounding list + warn on mismatch.
C. Pipe-in-Markdown-table-row (3+ PRs). Regex check on table rows
   for unescaped `|` inside code spans.

Effort: M. Each class ~20-50 lines of regex + tests. Could land
as separate scripts or combined `tools/lint/doc-lint.sh`. Wire
into pre-commit + gate.yml per existing lint-script convention.

Composes with lower-density candidate classes (D-F) from the
multi-CLI capability-map cluster + shellcheck-rule-ID precision +
stable-identifier-vs-line-number xref — promote when density
justifies. References `docs/pr-preservation/_patterns.md` (PR #448).

Compounding with Otto-114 forward-mirror substrate fix: structural
change converts per-PR fix-toil into never-recurring class. The
3+ existing classes have already paid for themselves in
verify-and-resolve replies; pre-commit-lint catches future
instances at author-time.

* hygiene(#465): fix 3 Copilot findings on the doc-lint BACKLOG row

- P1 :4481 — Class B regex example: keep `\b\d+\s+...\b` on a single
  line of backticks (was crossing newline, rendering as two adjacent
  spans rather than one regex; ironically a Class A pattern instance
  inside the Class A description).
- P2 :4488 — Class C: cite markdownlint rule by full identifier
  `MD056/table-column-count` (consistent with how it's recorded in
  docs/pr-preservation/141-ci-fix-log.md:35; helps grep-ability).
- P2 :4501 — keep `stable-identifier-vs-line-number` contiguous
  (was hard-wrapped mid-token as `stable-identifier-vs-line-` /
  `number`, rendering as 'line- number' with extra space).

All three findings are pattern instances of classes this same
BACKLOG row promotes to lint-suite candidates — appropriate
self-application.
AceHack added a commit that referenced this pull request Apr 25, 2026
…reword) (#447)

* hygiene(#268): pr-preservation drain-log for #435 (live-lock cadence reword)

Otto-268 backfill: drain-log for PR #435 (drain follow-up to #148:
why-the-factory-is-different live-lock cadence claim + grammar),
covering 3 threads across 2 waves with a clean self-induced-cascade
pattern.

Per Otto-250 training-signal discipline. Pattern observations capture
four load-bearing patterns:
1. Cross-reviewer convergence on Wave 1 (Codex P2 + Copilot P1
   flagging the same missing-FACTORY-HYGIENE-row) raised quality
   signal — same shape as #432's `warn` unbound finding.
2. Self-induced cascade: my Wave-1 fix introduced the Wave-2
   finding (claim "separate BACKLOG items" implied plural; actual
   BACKLOG state is one row with multiple sub-items). Pattern: when
   fixing a claim, verify the new claim is also accurate against
   current-state.
3. Reword-option-(a)-vs-(b) decision template generalizes: when
   doc asserts X but X doesn't exist, prefer reword-to-current-truth
   over add-the-thing-asserted (unless thing is small + isolated).
4. PR-mechanics: 4 of 7 cascade-PRs in this session (#135, #231,
   #432, #435) went through wave-1 + wave-2 cascade pattern; the
   reviewer-cascade is a consistent property of the merge-trigger
   surface, not a per-PR oddity.

Closes the session-drain-log backfill (Otto-268) for the major PRs
drained in this session: #135 / #235 / #432 / #434 / #195 / #219 /
#206 / #377 / #231 / #85 / #435 (11 PRs total covered across drain
logs #437-#447).

* drain(#447 follow-up): fix #435 drain-log Reviewer field + stable-identifier xref

Codex P2 + Copilot threads on #447 caught:

- Thread 1.2 missing the `Reviewer:` field even though the drain-log
  schema (intro paragraph) declares per-thread reviewer authorship.
  Added `Reviewer: copilot-pull-request-reviewer`.
- Stale `docs/BACKLOG.md lines 1313-1328` citation: those lines now
  contain the Server Meshing section; the live-lock-smell cadence
  row drifted to ~L1452 in the P1 tooling section. Replaced with
  the stable identifier (heading text 'Live-lock smell cadence
  (round 44 auto-loop-46 absorb, landed as `tools/audit/
  live-lock-audit.sh` + hygiene-history log)') so future readers
  don't chase a moving line-number target.

Same stable-identifier-vs-line-number-xref pattern flagged on
#423's `near line 4167` finding. Documented in `_patterns.md` —
line numbers decay on every adjacent edit; stable identifiers
decay only on rename. Adopting heading text as the stable cite.

The bare `:111`/`:113` thread location format (Otto-250 file:line
shape conformance) is the broader Otto-268-wave divergence
documented in PR #467 known-divergence section — deferred to
maintainer review per that framing.
AceHack added a commit that referenced this pull request Apr 25, 2026
…cture ADR) (#446)

Otto-268 backfill: drain-log for PR #85 covering 11 threads (10 IDs +
1 dup) across 7 distinct fixes + 1 surface-class. High density of
internal-consistency findings (5 of 7) — tier-scheme vs directory-tree
gap, id-vs-filename inconsistency, "never edit / hand-append"
contradiction, `tools/migrations/` claimed-vs-actual, PR-description
vs ADR directory name.

Per Otto-250 training-signal discipline. Pattern observations capture
four load-bearing patterns:
1. Internal-consistency-finding density on draft ADRs (5 of 7) —
   draft ADRs evolve their own self-references during authoring;
   reviewers catch the accumulated inconsistencies.
2. Otto-279 surface-class for ADRs as history-class preserved
   provenance — stripping decision-maker names would break audit
   chain.
3. Live-count vs frozen-count drift as findings class; fix template
   is order-of-magnitude approximation + drift-tolerance note.
4. Stale-merge-commit-on-PR-head needed force-push reconciliation;
   rebase + force-push sometimes appears to "lose content" against
   a stale merge-commit head, actually fixes content equivalence.
AceHack added a commit that referenced this pull request Apr 25, 2026
…e ADR

P1 (L36) — id-vs-filename consistency: \`<id>.md\` vs
\`<slug>-<YYYY-MM-DD>.md\` ambiguity reconciled — the slug-date stem IS
the row's id; clarified inline.

P1 (L36+L59) — PR description vs ADR directory name (docs/backlog-rows/
vs docs/backlog/): added explicit reconciliation note marking
\`docs/backlog/\` as canonical for the ADR; PR description references
historical wording.

P1 (L68) — declined tier scheme without declined/ folder: added
\`docs/backlog/declined/\` to the directory tree alongside shipped/.

P1 (L140) — "never edit index" + "hand-append" contradiction reworded:
existing index entries are read-only; new rows may append a new index
line OR leave to next regeneration. Index ordering/formatting is
generator output, not authoring surface.

P1 (L275) — tools/migrations/ as established convention claim was
inaccurate (subtree doesn't exist). Reframed as "Proposed convention
for this ADR" + adopting it requires creating the directory as part
of implementation.

P2 (L13) — line count drift (5,957 → ~6k): used order-of-magnitude
figure with explicit note that live count drifts as backlog grows.

P2 (L234) — trailing \`+\` continuation reformatted to use commas /
"and" (no editing-artifact line break).

The "Aaron/Kenji/..." name finding (L5) is replied separately per
Otto-279 — \`docs/DECISIONS/\` is a history-class surface and first-name
attribution is allowed there alongside docs/research/, ROUND-HISTORY,
aurora/, pr-preservation/.
@AceHack AceHack disabled auto-merge April 25, 2026 09:16
@AceHack AceHack enabled auto-merge (squash) April 25, 2026 09:16
@AceHack
Copy link
Copy Markdown
Member Author

AceHack commented Apr 25, 2026

Superseded by #474 (fresh branch off current main with same content + swim-lane variant added per Aaron 2026-04-25). The stale check_runs (macos-14/ubuntu-22.04/Analyze (csharp)) on this PR's head SHA couldn't be cleared via rebase + workflow_dispatch — the rolled-up checks attach permanently to that SHA. Fresh branch + fresh PR is the clean fix.

Closed by Otto post-Aaron "you can just redo the work if you like and split, it's likely easy to start from master and just remake the code changes" (2026-04-25).

@AceHack AceHack closed this Apr 25, 2026
auto-merge was automatically disabled April 25, 2026 12:39

Pull request was closed

AceHack added a commit that referenced this pull request Apr 25, 2026
…ersedes #85) (#474)

* docs: ADR draft — BACKLOG-per-row-file restructure

Decision record for the proposed restructure of `docs/BACKLOG.md`
from a 6500-line monolith into per-row files under
`docs/backlog/<topic>/<row-id>.md`.

This ADR is the *decision* — implementation is a separate M/L
follow-up that updates every BACKLOG-touching script (audits,
generators, indices) to scan the per-row directory instead of
parsing the monolith.

## Why a separate fresh branch (not a rebase of #85)

Original PR #85 (`land-backlog-per-row-file-batch5`) was based on
an older main and accumulated stale CI check_runs (`macos-14`,
`ubuntu-22.04`, `Analyze (csharp)`) from a workflow that no longer
exists. The current matrix is `macos-26`/`ubuntu-24.04`/etc.
Rebase + workflow_dispatch couldn't override the rolled-up stale
checks.

Fresh branch off current main reproduces the same content (same
ADR file, identical 306 lines) and gets clean CI on the current
matrix. Per Aaron 2026-04-25 "you can just redo the work if you
like and split, it's likely easy to start from master and just
remake the code changes."

PR #85 will be closed as superseded once this lands.

* docs(adr): add swim-lane variant per Aaron 2026-04-25

Aaron 2026-04-25: 'we can have backlog by swimlane if you think
that's better than per file.'

Swim-lane (per-domain/per-owner: docs/backlog/security.md,
research.md, factory-demo.md, ci.md, governance.md, etc.) is
strictly better than per-row on three axes:

- Discoverability: ~10-15 swim-lane files vs ~150+ per-row files;
  each swim-lane is grep-able as a single coherent topic.
- Tooling cost: scripts scan a small fixed set of swim-lane files;
  no dynamic directory walk; index-file generation simpler.
- Reordering: tier ordering stays as section headers within a
  swim-lane file (lighter ceremony than filename-encoded moves).

Per-row is strictly better on collision avoidance (filename
disambiguates), so retained as a future option if collision rate
under swim-lane proves insufficient.

ADR title + Status updated to capture both variants. Implementation
PR will land swim-lane first; per-row stays as fallback. The
'Alternatives considered' section #5 now describes the swim-lane
trade-off matrix in full.

* docs(adr): correct per-row dismissal — priority-in-frontmatter variant is viable

Aaron 2026-04-25 caught the overstatement: 'Filename IS the index
entry. is that not a benefit we could get with per row file
backlog?'

Yes — the original ADR's per-row variant encoded priority in the
directory path (docs/backlog/p1/...), which created a 'rename on
every P3→P1 shift' pattern. But a corrected per-row variant with
priority-in-frontmatter (filename = topic+owner-ref, priority in
YAML) keeps the filename-IS-index benefit while avoiding the
rename ceremony.

Add as alternative #6 with a trade-off matrix comparing all three
viable approaches (per-row priority-in-path, per-row priority-in-
frontmatter, swim-lane). Real trade-off is tooling-investment-now
(per-row) vs simpler-grep-now (swim-lane). Maintainer's current
lean is still swim-lane for initial implementation, but per-row
priority-in-frontmatter is now an active alternative not a
rejected one.

* docs(adr): drop the rename-ceremony objection

Aaron 2026-04-25: '"rename on every priority change" that's
fine it would have been an edit anyways'.

He's right — file rename and in-place edit are the same cost (one
git operation, similarity-tracked). The 'rename ceremony'
objection in earlier ADR revisions was non-substantive. Drop it
from the trade-off matrix.

This further weakens the case for swim-lane over per-row. Net
result: both variants are now strictly viable on equal terms.
Per-row is collision-avoidance-better; swim-lane is
zero-tooling-better. Maintainer no longer expresses a preference
between the two. Implementation PR will pick one and migrate.

* docs(adr): finalise decision — per-row, priority-in-frontmatter

Aaron 2026-04-25 delegated the final call to Otto. Decision: per-row
with priority-in-frontmatter.

Reasoning:
1. Pattern consistency — matches every other write-many-edit-rarely
   surface (memory, ADRs, drain logs, skills); BACKLOG is the holdout
   with the same access pattern.
2. Filename-IS-index at per-row level (Aaron's framing).
3. Tooling burden bounded (~200 LOC: index script + frontmatter
   parser); factory has equivalent tooling for memories.
4. Mark-as-done = move-or-delete-file (cleaner than mutating a
   1000-line swim-lane file).
5. Strictly better collision avoidance post-R45 EnterWorktree
   default-flip when parallel branches multiply.

Swim-lane retained in the alternatives matrix as documentation of
the second-best option; would be acceptable fallback if the per-row
tooling investment proves larger than expected.

* docs(adr): fix MD029 ordered-list numbering after iterations

Markdownlint MD029 caught the alternatives list out of sequence
(items 5, 6 came before original 3, 4 because earlier revisions
appended new alternatives without reflowing). Reorder to 1-6
sequential. Also drop the duplicated 'status-quo' and
'automated-resolver' items at the bottom — they're now in
correct positions in the main list.

Same Class A pattern (line-leading numbering after content
shifts) caught by markdownlint.

* docs(adr): align with Otto-181 substrate (existing tooling)

Resolves all 13 copilot review threads on PR #474. The ADR's
prior draft was written without first reading the existing
substrate — `tools/backlog/generate-index.sh` and
`docs/backlog/P[0-3]/` already exist (Otto-181 prior work),
and one example row was already migrated. The draft proposed
a competing schema and competing scripts.

Substantive changes:

- **Reframe the ADR.** This is no longer "decide to do per-row"
  (Otto-181 already decided that). It's "commit to bulk-
  migrating the remaining ~350 rows into the existing
  Otto-181 substrate."
- **Add an "Existing substrate" section** acknowledging
  Otto-181 design + `tools/backlog/generate-index.sh` +
  `docs/backlog/P[0-3]/` + the one example row already
  migrated.
- **Align schema with reality.** The Otto-181 schema is
  `id: B-<NNNN>`, `priority`, `status`, `title`, `tier`,
  `effort`, `directive`, `created`, `last_updated`,
  `composes_with`, `tags`. Drop the `<slug>-<YYYY-MM-DD>`
  filename + `owner` / `updated` / `scope` field proposals
  that did not match the parser.
- **Fix script references.** The actual script is
  `tools/backlog/generate-index.sh` (not
  `regenerate-index.sh`). `lint-index.sh` is owed (Phase 1c)
  — explicitly noted as a wrapper around
  `generate-index.sh --check`.
- **Update line count.** From "~6k" / "5,957" to "~12,800"
  (12,781 measured at time of writing).
- **Fix markdown formatting.** Renumber the Alternatives
  section sequentially 1-6. Fix the trade-off matrix
  rendering (was `||`, now `|`). Reduce the matrix to two
  columns since "per-row priority-in-path" was rejected.
- **"Maintainer's current lean" ambiguity** resolved — the
  Decision section now states the call concretely (per-row
  with Otto-181 schema), no longer leaves it to the
  implementation PR.

Threads addressed:

- PRRT_kwDOSF9kNM59lW9I — schema mismatch
- PRRT_kwDOSF9kNM59lW9O — id semantics inconsistency
- PRRT_kwDOSF9kNM59lW9S — index "auto-generated or manual"
- PRRT_kwDOSF9kNM59lW9U — `regenerate-index.sh` typo
- PRRT_kwDOSF9kNM59lW9V — `lint-index.sh` non-existent
- PRRT_kwDOSF9kNM59lW9X — naming/ID scheme misalignment
- PRRT_kwDOSF9kNM59lYZK — alternatives numbering 1,2,5,6,3,4
- PRRT_kwDOSF9kNM59lYZN — table extra `|` rendering
- PRRT_kwDOSF9kNM59lYZS — `lint-index.sh` cite
- PRRT_kwDOSF9kNM59lYZV — line count drift
- PRRT_kwDOSF9kNM59lYZZ — "maintainer's lean" ambiguity
- PRRT_kwDOSF9kNM59lYZd — script path mismatch
- PRRT_kwDOSF9kNM59lYZi — line count factual error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants